package com.sbj.config;

import cn.dev33.satoken.stp.StpUtil;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.sbj.dto.req.BuyReq;
import com.sbj.entity.BuyGoods;
import com.sbj.entity.MemberStore;
import com.sbj.entity.OrderTime;
import com.sbj.service.IBuyGoodsService;
import com.sbj.service.IMemberStoreService;
import com.sbj.service.OrderTimeService;
import com.zmh.framework.constants.Constants;
import com.zmh.framework.exception.AbnormalException;
import com.zmh.framework.exception.ResultException;
import com.zmh.framework.redis.RedisCache;
import lombok.AllArgsConstructor;
import org.redisson.api.RLock;

import org.springframework.context.annotation.Configuration;


import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author summer
 * @version 1.0
 * @date 2024/8/27 19:35
 */
@Configuration
@AllArgsConstructor

public class BuyOrderConfig {


    private  final RedisCache redisCache;

    private final OrderTimeService orderTimeService;




    /**
     * 抢购订单
     * @param req
     */
    public void submitBuyOrder(BuyReq req){
        RLock lock = redisCache.lock("buy:"+req.getId());
        Integer loginId = StpUtil.getLoginIdAsInt();
        try {
            List<OrderTime> orderTimeList = orderTimeService.list();
            if(CollUtil.isNotEmpty(orderTimeList) && orderTimeList.size()>0){
                LocalTime endTime = orderTimeList.get(Constants.ZERO).getEndTime();
                LocalDateTime firstDateTime = LocalDateTime.of(LocalDate.now(), endTime);
                if(LocalDateTime.now().isAfter(firstDateTime)){
                    throw new AbnormalException("抢购已结束");
                }
            }
            boolean tryLock = lock.tryLock(100, 10, TimeUnit.SECONDS);
            if (tryLock) {
                IMemberStoreService memberStoreService = SpringUtil.getBean(IMemberStoreService.class);
                IBuyGoodsService buyGoodsService = SpringUtil.getBean(IBuyGoodsService.class);
                BuyGoods buyGoods = buyGoodsService.getById(req.getId());
                if(buyGoods.getStatus().equals(Constants.ONE)){
                    throw new ResultException("商品已出售");
                }
                 MemberStore  memberStore = new MemberStore();
                 memberStore.setBuyId(req.getId());
                 memberStore.setOrderNo("C"+ RandomUtil.randomNumbers(12));
                 memberStore.setGoodsPrice(buyGoods.getGoodsPrice());
                 memberStore.setGradTime(LocalDateTime.now());
                 memberStore.setOrderTime(LocalDateTime.now());
                if(buyGoods.getGrounding().equals(Constants.ONE)){
                    memberStore.setSellerId(buyGoods.getMemberId());
                    MemberStore store = memberStoreService.getById(buyGoods.getBuyOrderId());
                    store.setBuyerId(loginId);
                    store.setGradTime(LocalDateTime.now());
                    memberStoreService.updateById(store);
                }
                memberStore.setBuyerId(loginId);
                memberStoreService.saveOrUpdate(memberStore);
                buyGoods.setStatus(Constants.ONE);
                buyGoodsService.updateById(buyGoods);

            }else{
                throw new ResultException("抢购失败");
            }
        }catch (Exception e){
            throw new ResultException(e.getMessage());
        }finally {
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }

    }

    public MemberStore memberStore(BigDecimal tradeAmount){
        MemberStore memberStore = new MemberStore();
        memberStore.setOrderNo("C"+ RandomUtil.randomNumbers(12));
        memberStore.setGoodsPrice(tradeAmount);
        memberStore.setOrderTime(LocalDateTime.now());
        memberStore.setSellerId(StpUtil.getLoginIdAsInt());
        memberStore.setOrderState(3);
        memberStore.setType(Constants.ONE);
        return memberStore;
    }

}
